package com.leyou.sh.trade.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.sh.auth.utils.UserContext;
import com.leyou.sh.common.exception.LyException;
import com.leyou.sh.item.client.ItemClient;
import com.leyou.sh.item.dto.SkuDTO;
import com.leyou.sh.trade.dto.OrderDTO;
import com.leyou.sh.trade.dto.OrderFormDTO;
import com.leyou.sh.trade.entity.Order;
import com.leyou.sh.trade.entity.OrderDetail;
import com.leyou.sh.trade.entity.OrderLogistics;
import com.leyou.sh.trade.entity.enums.OrderStatus;
import com.leyou.sh.trade.mapper.OrderMapper;
import com.leyou.sh.trade.service.OrderDetailService;
import com.leyou.sh.trade.service.OrderLogisticsService;
import com.leyou.sh.trade.service.OrderService;
import com.leyou.sh.user.client.UserClient;
import com.leyou.sh.user.dto.AddressDTO;
import feign.FeignException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author balisong_fcs
 * @date 2021/1/17 21:54
 * @desc
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order>implements OrderService {
    @Autowired
    private ItemClient itemClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private OrderDetailService detailService;
    @Autowired
    private OrderLogisticsService logisticsService;

    @Override
    @Transactional
    public Long createOrder(@Valid OrderFormDTO orderFormDTO) {
        //1.写Order
        Order order = new Order();
        //1.1 设置订单用户属性
        order.setUserId(UserContext.getUser().getId());
        //1.2
        //订单金额设置 key为商品id,value值为商品数量
        Map<Long, Integer> carts = orderFormDTO.getCarts();
        //1.3 set集合转化为list集合获取商品得ids
        List<Long> idList = new ArrayList<>(carts.keySet());
        //查询商品
        List<SkuDTO> skuDTOS = this.itemClient.querySkuByIds(idList);
        //计算总价
        long total = 0;
        for (SkuDTO skuDTO : skuDTOS) {
            total += skuDTO.getPrice() * carts.get(skuDTO.getId());
        }
        order.setTotalFee(total);
        order.setPaymentType(orderFormDTO.getPaymentType());
        order.setPostFee(0L);
        order.setActualFee(total + order.getPostFee());

        //1.3 订单状态初始化
        order.setStatus(OrderStatus.INIT);
        //1.4 将订单写入数据库
        boolean success = this.save(order);
        if (!success) {
            throw new LyException(500, "创建订单失败");
        }
        List<OrderDetail> detailList = new ArrayList<>();
        //设置商品数量
        for (SkuDTO skuDTO : skuDTOS) {
            OrderDetail orderDetail = new OrderDetail();
            //获取每一件订单商品得数量
            orderDetail.setNum(carts.get(skuDTO.getId()));
            //设置订单id关联
            orderDetail.setOrderId(order.getOrderId());
            //设置图片信息
            orderDetail.setImage(StringUtils.substringBefore(skuDTO.getImages(), ","));
            //设置skuid
            orderDetail.setSkuId(skuDTO.getId());
            //设置参数信息
            orderDetail.setSpec(skuDTO.getSpecialSpec());
            //设置单加
            orderDetail.setPrice(skuDTO.getPrice());
            //设置标题
            orderDetail.setTitle(skuDTO.getTitle());
            //封装每个orderDetails到集合
            detailList.add(orderDetail);
        }
        //批量新增
         boolean success2 = this.detailService.saveBatch(detailList);
        if (!success2) {
            throw new LyException(500, "创建订单失败");
        }
        //设置orderLogistics
        //查询收获地址
        AddressDTO addressDTO = this.userClient.queryAddressById(orderFormDTO.getAddressId());
        //填写物流信息
        OrderLogistics orderLogistics = addressDTO.toEntity(OrderLogistics.class);
        //设置其OrderId
        orderLogistics.setOrderId(order.getOrderId());
        //数据库写入数据
        boolean success3 = this.logisticsService.save(orderLogistics);
        if (!success3) {
            throw new LyException(500, "创建订单失败");
        }
        //添加订单,维护数据表完成,还有将维护商品表中得库存和销量字段
        //减库存
        try {
            this.itemClient.deductStock(carts);
        } catch (FeignException e) {
            throw new LyException(e.status(), e.getMessage());
        }
        //返回订单编号
        return order.getOrderId();
    }

    @Override
    public OrderDTO queryOrderById(Long orderId) {
        return new OrderDTO(this.getById(orderId));
    }
}
